﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Lobby : Window
    {
        public delegate void RequestQuery(String message);
        public RequestQuery requestQuery;

        private static String ClientUsername;

        private String privateMessageUsername;
        public List<String> playerList;

        private GameAdminLobby gameadminlobby;
        private GameLobby gamelobby;

        private String gameid;

        public Lobby(String username, String clientURL, String serverURL)
        {
            ClientUsername = username;
            InitializeComponent();
            new GameList();
            playerList = new List<String>();

            requestQuery = new RequestQuery(decipherServerQuery);
            new HTTP(requestQuery, clientURL, serverURL);

            decipherServerQuery(HTTP.GETfromServer("type=player&subtype=all&username="+username));
            HTTP.sendToServer("type=game&subtype=all&username="+username);

            String oldMessages = HTTP.GETfromServer("getchat", "");
            if(oldMessages != "")
                foreach (String s in oldMessages.Split('-'))
                {
                    lobbyChatList.Items.Add(s);
                }


            privateMessageUsername = "";

            Closing += Lobby_Closing;

            lobbyChatTextBox.Focusable = true;
            lobbyChatTextBox.Focus();
        }

        void Lobby_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            try
            {
                if (gameadminlobby != null)
                {
                    gameadminlobby.Close();
                    HTTP.sendToServer("type=game&subtype=remove&gameid=" + gameid);
                }
                if (gamelobby != null)
                {
                    HTTP.sendToServer("type=ingame&subtype=remove-player&gameid=" + gameid + "&player=" + Lobby.getUsername());
                    gamelobby.Close();
                }
                HTTP.sendToServer("type=player&subtype=remove&username=" + ClientUsername);
                HTTP.chatThread.Abort();
                HTTP.closeConnection();
            }
            catch { }
        }


        public void decipherServerQuery(String m)
        {
            if (m == "enableCreateGame")
            {
                lobbyCreateGameButton.IsEnabled = true;
                lobbyLogoutButton.IsEnabled = true;
                lobbyQuitButton.IsEnabled = true;
                return;
                gameadminlobby = null;
                gamelobby = null;
            }
            String[] splitMessage = m.Split('&');
            String type = "";
            String aux1 = "";
            String aux2 = "";
            String aux3 = "";
            String aux4 = "";
            String aux5 = "";
            String aux6 = "";
            String aux7 = "";

            foreach (String line in splitMessage)
            { 
                String[] data = line.Split('=');
                if (data[0] == "type")
                {
                    type = data[1];
                }
                else
                {
                    if (type == "chat")
                    {
                        if (data[0] == "username")
                        {
                            aux1 = data[1];
                        }
                        else if (data[0] == "message")
                        {
                            aux2 = data[1];
                        }
                        else if(data[0] == "personal")
                        {
                            aux3 = data[1];
                        }
                    }
                    if (type == "game")
                    {
                        if (data[0] == "subtype")
                        {
                            aux1 = data[1];
                        }
                        else if (data[0] == "gamename")
                        {
                            aux2 = data[1];
                        }
                        else if (data[0] == "ipaddress")
                        {
                            aux3 = data[1];
                        }
                        else if (data[0] == "id" || data[0] == "gameid")
                        {
                            aux4 = data[1];
                        }
                        else if (data[0] == "settings")
                        {
                            aux5 = data[1];
                        }
                        else if (data[0] == "username")
                        {
                            aux6 = data[1];
                        }
                    }
                    if (type == "player")
                    {
                        if (data[0] == "subtype")
                        {
                            aux1 = data[1];
                        }
                        else if (data[0] == "name")
                        {
                            aux2 = data[1];
                        }
                    }
                }
            }

            if (type == "chat")
            {
                String username = aux1;
                String message = aux2;
                String personal = aux3;
                lobbyChatList.Dispatcher.BeginInvoke(new Action(delegate()
                {
                    lobbyChatList.Items.Add(personal != "" ? username+"(personal:"+personal+"): " : username+": " + message);
                }));
            }
            else if (type == "game")
            {
                String subtype = aux1;
                String gamename = aux2;
                String ip = aux3;
                String gameid = aux4;
                String settings = aux5;
                //String maxPlayers = HTTP.decipherGameType(sett[0]);
                //String lives = sett[1];
                //String time = sett[2];
                String username = aux6;

                lobbyGameList.Dispatcher.BeginInvoke(new Action(delegate()
                {
                    if (subtype == "add")
                    { 
                        GameList.addGame(new Game(gamename, ip, gameid, username, settings));
                        lobbyGameList.Items.Add(gamename);
                    }
                    else if (subtype == "remove")
                    {
                        
                        for (int i = 0; i < lobbyGameList.Items.Count; i++)
                        {
                            if (lobbyGameList.Items[i].ToString() == GameList.getGame(gameid).getName())
                            {
                                lobbyGameList.Items.RemoveAt(i);
                            }
                        }
                        GameList.removeGame(gameid);
                        //lobbyGameList.Items.RemoveAt(lobbyGameList.Items.IndexOf());
                    }
                }));
            }
            else if (type == "player")
            {
                String subtype = aux1;
                String name = aux2;
                lobbyPlayerList.Dispatcher.BeginInvoke(new Action(delegate()
                {
                    if (subtype == "add")
                    {
                        playerList.Add(name);
                        lobbyPlayerList.Items.Add(name);
                    }
                    else if (subtype == "remove")
                    {
                        playerList.RemoveAt(playerList.IndexOf(name));
                        lobbyPlayerList.Items.RemoveAt(lobbyPlayerList.Items.IndexOf(name));
                    }
                    else if (subtype == "all")
                    { 
                        String[] names = name.Split('-');
                        foreach(String n in names)
                            lobbyPlayerList.Items.Add(n);
                    }
                }));
            }
        }

        public static String getUsername()
        {
            return ClientUsername;
        }

        private void PlayerInformation_PlayerMenu_Click(object sender, RoutedEventArgs e)
        {
            getPlayerInformation();
        }

        private void JoinGame()
        {
            try
            {
                Game g = GameList.getGame(lobbyGameList.SelectedValue.ToString());
                String gameData = HTTP.GETfromServer("type=ingame&subtype=add-player&gameid=" + g.getId() + "&player=" + ClientUsername);
                if (gameData != "failure")
                {
                    String gamename = "";
                    String players = "";
                    String maxPlayers = "";
                    String lives = "";
                    String time = "";
                    String id = "";
                    foreach (String data in gameData.Split('&'))
                    {
                        String[] dataline = data.Split('=');
                        if (dataline[0] == "gamename")
                        {
                            gamename = dataline[1];
                        }
                        else if (dataline[0] == "players")
                        {
                            players = dataline[1];
                        }
                        else if (dataline[0] == "maxplayers")
                        {
                            maxPlayers = dataline[1];
                        }
                        else if (dataline[0] == "lives")
                        {
                            lives = dataline[1];
                        }
                        else if (dataline[0] == "time")
                        {
                            time = dataline[1];
                        }
                        else if (dataline[0] == "gameid" || dataline[0] == "id")
                        {
                            id = dataline[1];
                        }
                    }
                    lobbyCreateGameButton.IsEnabled = false;
                    lobbyLogoutButton.IsEnabled = false;
                    lobbyQuitButton.IsEnabled = false;
                    gameid = id;
                    gamelobby = new GameLobby(requestQuery, gamename, players, maxPlayers, lives, time, id);
                    gamelobby.Show();
                }
                else
                {
                    MessageBox.Show("Could not join game.");
                }
            }
            catch { }
        }

        private void JoinGame_GameMenu_Click(object sender, RoutedEventArgs e)
        {
            JoinGame();
        }

        private void GameInformation_GameMenu_Click(object sender, RoutedEventArgs e)
        {
            
            getGameInformation();
        }

        private void lobbyChatTextBox_OnKeyDownHandler(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                sendMessageToServer();
            }
        }

        private void getGameInformation()
        {
            Game g = GameList.getGame(lobbyGameList.SelectedValue.ToString());
            int lives = Convert.ToInt32(g.getLives().ToString());
            String time = g.getTimeLength().ToString();
            String matchType = g.getMaxPlayers().ToString();
            String gamename = g.getName();

            lobbyInformationLabel.Content = "Game: " + gamename + "\n\tLives: " + lives/2+"v"+lives/2 + "\t\tMatchType: " + matchType + "\n\tTime: " + time;
        }
/*
        private void playerlistBoxItem_Click(object sender, RoutedEventArgs e)
        {
            lobbyPlayerList.SelectedIndex = -1;
            getPlayerInformation();
        }
 * */

        private void PrivateMessage_PlayerMenu_Click(object sender, RoutedEventArgs e)
        {
            privatePlayerMessage();
        }

        private void privatePlayerMessage()
        {
            privateMessageUsername = lobbyPlayerList.SelectedValue.ToString();
            lobbyPrivateMessageGroupBox.Header = privateMessageUsername;
        }

        private void CancelPrivateMessage_PlayerMenu_Click(object sender, RoutedEventArgs e)
        {
            cancelPrivatePlayerMessage();
        }

        private void cancelPrivatePlayerMessage()
        {
            lobbyPrivateMessageGroupBox.Header = "All:";
            privateMessageUsername = "";
        }

        private void gamelistBoxItem_DoubleClick(object sender, RoutedEventArgs e)
        {
            MessageBoxResult messageResult = MessageBox.Show("Join game?", "Would you like to join this game?", MessageBoxButton.YesNo);
            if (messageResult == MessageBoxResult.Yes)
            {
                JoinGame();
            }
        }

        private void playerlistBoxItem_DoubleClick(object sender, RoutedEventArgs e)
        {
            if (privateMessageUsername == "")
            {
                privatePlayerMessage();
            }
            else
            {
                cancelPrivatePlayerMessage();
            }
        }

        private void getPlayerInformation()
        {
            
            String playerData = HTTP.GETfromServer("type=player&subtype=getinfo&username=" + lobbyPlayerList.SelectedValue.ToString());
            String[] playerDataArray = playerData.Split('-');
            lobbyInformationLabel.Content = "Player: " + playerDataArray[0] + "\n\tPlayerName: " + playerDataArray[1] + "\t\tWins: " + playerDataArray[3] + "\n\tE-Mail:" + playerDataArray[2] + "\t\tLosses:" + playerDataArray[4];
        }

        private void lobbySendChatButton_Click(object sender, RoutedEventArgs e)
        {
            sendMessageToServer();
        }

        private void sendMessageToServer()
        {
            if (privateMessageUsername != "")
            {
                if (HTTP.GETfromServer("type=chat&username=" + ClientUsername + "&message=" + lobbyChatTextBox.Text.ToString().Replace(" ", "_~~~_~_~~~_")) != "success")
                {
                    MessageBox.Show("Error.");
                }
            }
            else
            {
                if (HTTP.GETfromServer("type=chat&username=" + ClientUsername + "&private=" + privateMessageUsername + "&message=" + lobbyChatTextBox.Text.ToString().Replace(" ", "_~~~_~_~~~_")) != "success")
                {
                    MessageBox.Show("Error.");
                }
            }
            lobbyChatTextBox.Text = "";
        }

        private void lobbyCreateGameButton_Click(object sender, RoutedEventArgs e)
        {
            lobbyCreateGameButton.IsEnabled = false;
            lobbyLogoutButton.IsEnabled = false;
            lobbyQuitButton.IsEnabled = false;
            gameid = Guid.NewGuid().ToString();
            (this.gameadminlobby = new GameAdminLobby(requestQuery, gameid)).Show();
        }


        private void lobbyLogoutButton_Click(object sender, RoutedEventArgs e)
        {
            HTTP.sendToServer("type=player&subtype=remove&username=" + ClientUsername);
            (new Login()).Show();
            this.Close();
        }

        private void lobbyQuitButton_Click(object sender, RoutedEventArgs e)
        {
            HTTP.sendToServer("type=player&subtype=remove&username=" + ClientUsername);
            this.Close();
        }

    }
}
